package com.klm.easymq.demo.service;

import com.klm.easymq.annotation.MQListener;
import com.klm.easymq.annotation.Retry;
import com.klm.easymq.demo.entity.Inventory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 库存服务类
 * 演示Easy-MQ SDK的消息消费者功能
 */
@Slf4j
@Service
public class InventoryService {
    
    // 模拟库存数据存储
    private final ConcurrentHashMap<String, Inventory> inventoryMap = new ConcurrentHashMap<>();
    private final AtomicInteger processedCount = new AtomicInteger(0);
    
    /**
     * 监听订单创建消息，扣减库存
     * 使用@MQListener注解自动消费消息
     */
    @MQListener(
        topic = "order.created",
        group = "inventory-service",
        idempotentKey = "#order.orderId",
        retryPolicy = @Retry(maxAttempts = 3)
    )
    public void handleOrderCreated(com.klm.easymq.demo.entity.Order order) {
        log.info("收到订单创建消息，开始扣减库存: orderId={}, productId={}", 
                order.getOrderId(), order.getProductId());
        
        try {
            // 模拟库存扣减逻辑
            Inventory inventory = getOrCreateInventory(order.getProductId(), order.getProductName());
            
            if (inventory.getCurrentStock() > 0) {
                // 扣减库存
                inventory.setCurrentStock(inventory.getCurrentStock() - 1);
                inventory.setUpdateTime(LocalDateTime.now());
                inventoryMap.put(order.getProductId(), inventory);
                
                log.info("库存扣减成功: productId={}, 剩余库存={}", 
                        order.getProductId(), inventory.getCurrentStock());
                
                // 更新处理计数
                processedCount.incrementAndGet();
                
            } else {
                log.warn("库存不足，无法扣减: productId={}", order.getProductId());
                throw new RuntimeException("库存不足");
            }
            
        } catch (Exception e) {
            log.error("处理订单创建消息失败: orderId={}", order.getOrderId(), e);
            throw e; // 重新抛出异常，触发重试机制
        }
    }
    
    /**
     * 监听订单取消消息，恢复库存
     */
    @MQListener(
        topic = "order.cancelled",
        group = "inventory-service",
        idempotentKey = "#order.orderId"
    )
    public void handleOrderCancelled(com.klm.easymq.demo.entity.Order order) {
        log.info("收到订单取消消息，开始恢复库存: orderId={}, productId={}", 
                order.getOrderId(), order.getProductId());
        
        try {
            Inventory inventory = inventoryMap.get(order.getProductId());
            if (inventory != null) {
                // 恢复库存
                inventory.setCurrentStock(inventory.getCurrentStock() + 1);
                inventory.setUpdateTime(LocalDateTime.now());
                inventoryMap.put(order.getProductId(), inventory);
                
                log.info("库存恢复成功: productId={}, 当前库存={}", 
                        order.getProductId(), inventory.getCurrentStock());
            }
            
        } catch (Exception e) {
            log.error("处理订单取消消息失败: orderId={}", order.getOrderId(), e);
        }
    }
    
    /**
     * 监听订单更新消息
     */
    @MQListener(
        topic = "order.updated",
        group = "inventory-service",
        idempotentKey = "#order.orderId"
    )
    public void handleOrderUpdated(com.klm.easymq.demo.entity.Order order) {
        log.info("收到订单更新消息: orderId={}, status={}", 
                order.getOrderId(), order.getStatus());
        
        // 这里可以添加订单状态变更的相关逻辑
        // 比如：订单支付成功后的库存锁定、订单发货后的库存释放等
    }
    
    /**
     * 获取或创建库存记录
     */
    private Inventory getOrCreateInventory(String productId, String productName) {
        return inventoryMap.computeIfAbsent(productId, k -> Inventory.builder()
                .productId(productId)
                .productName(productName)
                .currentStock(100) // 初始库存100
                .lockedStock(0)
                .totalStock(100)
                .updateTime(LocalDateTime.now())
                .build());
    }
    
    /**
     * 获取库存信息
     */
    public Inventory getInventory(String productId) {
        return inventoryMap.get(productId);
    }
    
    /**
     * 获取所有库存信息
     */
    public ConcurrentHashMap<String, Inventory> getAllInventory() {
        return inventoryMap;
    }
    
    /**
     * 获取已处理的消息数量
     */
    public int getProcessedCount() {
        return processedCount.get();
    }
} 